import React, { Component } from 'react';
import WPT from 'wpt';
import cx from 'classnames';
import CountryCodeList from 'modules/verifyTelephoneModal/countryCodeList/CountryCodeList';
import { throttle } from 'modules/RX';
import sliderCheck from 'modules/sliderCheck';
import { loginReport } from 'modules/ReportAjax';
import NewConfirm from './newConfirm';
import Util from '../../util';
import S from './index.m.less';

const API = {
    sendCode: `${WPT.API_HOST}app/v1.0/user/send-login-code`, // 发送验证码接口
    login: `${WPT.API_HOST}app/v1.0/user/login`, // 登录接口
};

class WptWapLogin extends Component {
    static defaultProps = {
        // 成功回调
        scb: () => {},
        // 失败回调
        fcb: () => {},
        // 用户关闭窗口回调
        ccb: () => {},
    };

    constructor(props) {
        super(props);
        this.state = {
            // 电话号码
            telephone: '',
            // 国家全称
            countryName: '中国大陆',
            // 国际区号
            countryCode: '86',
            // 手机号正则规则
            pattern: '^(86){0,1}1\\d{10}$',
            // 验证码重发倒计时 60s
            seconds: '60',
            // 展示区号选择界面
            showCountryCode: false,
            // 展示验证码输入界面
            showCodeInputPage: false,
            // 验证码
            code: '',
            // 滑动验证码返回数据
            sliderData: {},
        };
    }

    componentDidMount() {
        this.numInput.focus();
    }

    componentWillUnmount() {
        this.interval = null;
    }

    // 电话号码正则校验
    canSubmit() {
        const { telephone, countryCode, pattern } = this.state;
        const reg = new RegExp(pattern);
        return reg.test(`${countryCode}${telephone}`);
    }

    // 发送验证码
    sendCode(data = {}) {
        const { telephone, countryCode } = this.state;
        const param = {
            telephone,
            type: countryCode == '86' ? 'call' : 'sms',
            nationCode: countryCode,
            ticket: data.ticket ? data.ticket : '',
            randstr: data.randstr ? data.randstr : '',
            tg: 1,
        };
        WPT.getData(API.sendCode, param, res => {
            if (res.code === 704) {
                WPT.Modal.tips(res.msg);
                this.setState(
                    {
                        showCodeInputPage: true,
                    },
                    () => {
                        this.countDownStart();
                        this.codeInput.focus();
                    }
                );
            } else if (res.code === 0) {
                WPT.Modal.tips('发送成功', { time: 800 });
                this.setState(
                    {
                        showCodeInputPage: true,
                        seconds: 60,
                    },
                    () => {
                        this.countDownStart();
                        this.codeInput.focus();
                    }
                );
            } else {
                WPT.Modal.tips(res.msg);
            }
        });
    }

    // 点击获取语音验证码
    handleNext = () => {
        const { countryCode, telephone } = this.state;
        if (!this.canSubmit()) return;
        sliderCheck({
            nationCode: countryCode,
            tel: telephone,
            callback: (obj, res = {}) => {
                this.setState({
                    sliderData: res,
                });
                WPT.Modal.open(
                    <NewConfirm
                        title="接受语音验证码"
                        contentOne="验证码将以电话的形式通知您，请留意接听最新来电。"
                        confirmCallback={() => {
                            this.sendCode(res);
                            WPT.Modal.close(false);
                        }}
                    />,
                    { layerClose: false }
                );
            },
        });
    };

    // 选择区号组件的回调函数
    setCountryInfo = (country, countryCode, pattern, countryName) => {
        this.setState({
            countryCode,
            pattern,
            countryName,
        });
    };

    // 控制显示“选择国家”组件
    setShowCountrycodeList = (value = true) => {
        this.setState({ showCountryCode: value });
    };

    // 国内手机号格式化 // 从选择区号页面返回时调用
    formatVerifyTelephone = () => {};

    // 切换为微信扫码登录
    gotoWxLogin = () => {
        ReactDOM.render(<PCLogin />, document.getElementById('wptLogin'));
    };

    // 渲染登录框
    renderLoginContainer = () => {
        const { telephone, countryName } = this.state;
        const { ccb } = this.props;
        return (
            <div className={cx(S.wptWapLogin)}>
                <div className={S.topBar}>
                    <div
                        className={cx(S.close)}
                        onClick={() => {
                            ccb && ccb();
                            $('#wptLogin').remove();
                        }}
                    />
                </div>
                <div className={S.inputContainer}>
                    <div className={S.countryCode} onClick={this.setShowCountrycodeList}>
                        {countryName}
                    </div>
                    <div className={S.columnDiliver} onClick={this.setShowCountrycodeList} />
                    <input
                        ref={d => {
                            this.numInput = d;
                        }}
                        maxLength={11}
                        placeholder="输入手机号码"
                        className={S.numInput}
                        value={telephone}
                        onChange={e => {
                            if (!/^[0-9]*$/.test(e.target.value)) return;
                            this.setState({
                                telephone: e.target.value,
                            });
                        }}
                    />
                </div>
                <div className={cx(S.next, !this.canSubmit() ? S.disabled : '')} onClick={this.handleNext}>
                    获取语音验证码
                </div>
                <div className={S.gotoWxLogin}>
                    <div className={S.wxIcon} onClick={this.gotoWxLogin} />
                    <div className={S.IconTitle} onClick={this.gotoWxLogin}>
                        微信扫码登录
                    </div>
                </div>
                {/* <div className={S.remindAgree}>
                登录即代表您同意微拍堂
                <div className={S.agreement}>《隐私保护协议》</div>
            </div> */}
            </div>
        );
    };

    // 渲染区号选择列表
    renderCountrycodeList = () => (
        <CountryCodeList
            setCountryInfo={this.setCountryInfo}
            setShowCountrycodeList={this.setShowCountrycodeList}
            formatVerifyTelephone={this.formatVerifyTelephone}
            noHistoryBack
        />
    );

    // 验证码重发倒计时开始
    countDownStart = () => {
        const { seconds } = this.state;

        if (!this.interval && seconds !== 0) {
            this.interval = setInterval(() => {
                this.setState(
                    {
                        seconds: this.state.seconds - 1,
                    },
                    () => {
                        if (this.state.seconds === 0) {
                            window.clearInterval(this.interval);
                            this.interval = null;
                        }
                    }
                );
            }, 1000);
        }
    };

    // 验证码重发按钮触发
    resendCode = () => {
        const { sliderData } = this.state;
        if (this.state.seconds !== 0) return;
        this.sendCode(sliderData);
    };

    setCookie(name, value, expiredays) {
        this.exdate = {};
        if (typeof expiredays === 'number') {
            this.exdate = new Date();
            this.exdate.setDate(this.exdate.getDate() + expiredays);
        } else if (typeof expiredays === 'object') {
            this.exdate = expiredays;
        }
        const string = expiredays == null ? '' : `;domain=.weipaitang.com;expires=${this.exdate.toGMTString()};path=/`;
        document.cookie = `${name}=${encodeURIComponent(value)}${string}`;
    }

    // 登录
    checkLogin = () => {
        const { code, telephone, countryCode } = this.state;
        if (code.length !== 4) return;
        const { scb } = this.props;
        const query = Util.query();
        const param = {
            type: 2,
            telephone,
            nationCode: countryCode,
            verifyCode: code,
            sc: sessionStorage.getItem('sc'),
            wpjbPromoter: query.wpjbPromoter || '',
        };
        WPT.getData(API.login, param, res => {
            if (res.code === 0 && res.data.cookie) {
                this.setCookie('userinfo_cookie', decodeURIComponent(res.data.cookie), 7);
                WPT.Modal.tips('登录成功');
                scb && scb();
                $('#wptLogin').remove();
            } else {
                WPT.Modal.tips(res.msg);
            }
        });
    };

    // 处理显示的手机号
    handleTelephone = () => {
        const { telephone, countryCode } = this.state;
        if (countryCode === '86') {
            return ` ${telephone.slice(0, 3)} ${telephone.slice(3, 7)} ${telephone.slice(7, 11)}`;
        }
        return ` +${countryCode} ${telephone}`;
    };

    // 渲染验证码输入页面
    renderCodeInputPage = () => {
        const { seconds, code } = this.state;
        const { ccb } = this.props;
        return (
            <div className={cx(S.wptCodeCheck)}>
                <div className={S.topBar}>
                    <div
                        className={cx(S.close)}
                        onClick={() => {
                            ccb && ccb();
                            $('#wptLogin').remove();
                        }}
                    />
                </div>
                <div className={S.remindTelephone}>
                    语音验证码已发送至
                    <span className={S.telephone}>{this.handleTelephone()}</span>
                </div>
                <div className={S.remindFrom}>请注意接听 0755/0578 等开头的来电</div>
                <div className={cx(S.inputContainer, seconds === 0 ? S.resend : '')}>
                    <input
                        ref={d => {
                            this.codeInput = d;
                        }}
                        maxLength={4}
                        placeholder="输入验证码"
                        className={cx(S.numInput, seconds === 0 ? S.resend : '')}
                        value={code}
                        onChange={e => {
                            if (!/^[0-9]*$/.test(e.target.value)) return;
                            this.setState({
                                code: e.target.value,
                            });
                        }}
                    />
                    {seconds === 0 ? (
                        <div className={S.resendBtn} onClick={this.resendCode}>
                            重新发送
                        </div>
                    ) : (
                        <div className={S.remindSeconds}>
                            {seconds}
s 后重新获取
                        </div>
                    )}
                </div>
                <div
                    className={cx(S.inputBtn, code.length === 4 ? '' : S.disabled)}
                    onClick={throttle(this.checkLogin, 1000)}
                >
                    确认
                </div>
            </div>
        );
    };

    render() {
        const { showCountryCode, showCodeInputPage } = this.state;
        return (
            <div className={S.loginMain}>
                {showCountryCode && this.renderCountrycodeList()}
                {!showCountryCode && !showCodeInputPage && this.renderLoginContainer()}
                {showCodeInputPage && this.renderCodeInputPage()}
            </div>
        );
    }
}

/**
 * 弹出手机号登录框
 * @param {function} scb 成功回调
 * @param {function} fcb 失败回调
 * @param {function} ccb 用户关闭窗口回调
 */
function showLogin(scb, fcb, ccb) {
    ReactDOM.render(<WptWapLogin scb={scb} fcb={fcb} ccb={ccb} />, document.getElementById('wptLogin'));
}

class PCLogin extends Component {
    static defaultProps = {
        // 成功回调
        scb: () => {},
        // 失败回调
        fcb: () => {},
        // 用户关闭窗口回调
        ccb: () => {},
        // 接口请求参数列表
        options: [],
    };

    state = {
        showUserinfo: false,
        imgUrl: '',
    };

    componentDidMount() {
        this.wsOpen = false;
        this.handleWS();
    }

    componentWillUnmount() {
        this.ws && this.ws.close();
        this.ws = null;
    }

    handleWS = () => {
        const { options, scb } = this.props;
        if (options.length < 2 || !this.wsOpen) {
            this.ws = new WebSocket(`${WPT.SCANLOGINHOST}pc/login`);
            this.ws.onopen = () => {
                this.wsOpen = true;
            };
            this.ws.onmessage = e => {
                const datajson = JSON.parse(e.data);
                if (datajson.type == 'refresh') {
                    this.showQrCode(datajson.data.src);
                }
                if (datajson.type == 'show') {
                    this.showUserinfo(datajson.data.headimgurl);
                }
                if (datajson.type == 'scope') {
                    const query = Util.query();
                    const SCANAPI = Util.handleApi({
                        scanInfo: '/v1.0/scanscope/login', // 进入页面扫码
                    });
                    WPT.getData(
                        SCANAPI.scanInfo,
                        {
                            token: datajson.data.token,
                            wpjbPromoter: query.wpjbPromoter || '',
                        },
                        res => {
                            if (res.code !== 0) {
                                return;
                            }
                            scb && scb();
                            WPT.Modal.tips('登录成功');
                            $('#wptLogin').remove();
                        }
                    );
                }
            };
            this.ws.onclose = () => {
                this.close();
            };
        }
    };

    // 刷新二维码
    showQrCode = reqdata => {
        $('#QRCode').find('img')[0]
            && $('#QRCode')
                .find('img')[0]
                .remove();
        // eslint-disable-next-line no-undef
        window.QRCode
            && this.qrCode
            // eslint-disable-next-line no-undef
            && new QRCode(this.qrCode, {
                width: 210,
                height: 210,
                text: reqdata,
            });
    };

    // 显示用户头像
    showUserinfo = imgUrl => {
        $('#QRCode').find('img')[0]
            && $('#QRCode')
                .find('img')[0]
                .remove();
        this.setState({
            showUserinfo: true,
            imgUrl,
        });
    };

    // 关闭 WebSocket 时触发
    close = () => {
        this.wsOpen = false;
        if (this.backScan) {
            this.handleWS();
            this.backScan = null;
        }
        this.setState({
            showUserinfo: false,
        });
    };

    // 切换为手机号登录
    switchToMobileLogin = () => {
        const { scb, fcb, ccb } = this.props;
        this.ws.close();
        showLogin(scb, fcb, ccb);
    };

    // 渲染扫描页面
    renderScanPage = () => (
        <div className={S.pcLogin}>
            <div
                className={S.QRcode}
                id="QRCode"
                ref={e => {
                    this.qrCode = e;
                }}
            >
                <div className={S.logo} />
            </div>
            <div className={S.title}>微信扫码登录</div>
            <div className={S.content}>
                <div className={S.scanIcon} />
                <div className={S.text}>
                    <div>打开微信，“扫一扫”</div>
                    <div className={S.bottom}>从发现，进入“扫一扫”，扫码登录</div>
                </div>
            </div>
            <div className={S.switch} onClick={this.switchToMobileLogin}>
                <div className={S.icon} />
                切换手机号登录
            </div>
        </div>
    );

    // 返回扫描页面
    backScanPage = () => {
        this.backScan = true;
        this.ws.close();
    };

    // 渲染确认页面
    renderConfirmPage = () => {
        const { imgUrl } = this.state;
        return (
            <div className={S.scanConfirmPage}>
                <div className={S.avatar} style={{ backgroundImage: `url(${imgUrl})` }} />
                <div className={S.title}>扫描成功</div>
                <div className={S.content}>请在手机上点击确认登录</div>
                <div className={S.backBtn} onClick={this.backScanPage}>
                    返回二维码扫描
                </div>
            </div>
        );
    };

    render() {
        const { showUserinfo } = this.state;
        return <div className={S.pcLoginLayer}>{showUserinfo ? this.renderConfirmPage() : this.renderScanPage()}</div>;
    }
}

/**
 * 弹出扫码登录框
 * @param {function} scb 成功回调
 * @param {function} fcb 失败回调
 * @param {function} ccb 用户关闭窗口回调
 * @param {array} options 接口请求参数列表
 */
function pcShowLogin(scb, fcb, ccb, options) {
    const wptLoginContainer = document.createElement('div');
    wptLoginContainer.setAttribute('id', 'wptLogin');
    $('body').append(wptLoginContainer);
    ReactDOM.render(<PCLogin scb={scb} fcb={fcb} ccb={ccb} options={options} />, wptLoginContainer);
}

const login = (function pcLogin() {
    let options = [];
    let isLoaded = false;

    function loginFuc(option, successCallback = () => {}) {
        if (option) {
            options.push(option);
        }
        if (!isLoaded) {
            pcShowLogin(
                () => {
                    WPT.loginRefreshUserinfo(() => {
                        WPT.isPCLogin = true;
                        WPT.loginCallback && WPT.loginCallback();
                        options.forEach(item => {
                            item._repeatAjax ? item._repeatAjax() : $.ajax(item);
                        });
                        options = [];
                        isLoaded = false;
                        loginReport(); // 触发登录上报
                        successCallback();
                    }, options);
                },
                () => {
                    isLoaded = false;
                },
                () => {
                    options = [];
                    isLoaded = false;
                },
                options
            );
            isLoaded = true;
        }
    }
    return loginFuc;
}());

export { login };
